const path = require('path');
const fs = require("fs");
const cProcess = require("child_process");
const cwd = process.cwd();
const dir = require("./dir.js");
const log = require("./log.js");
const type = require("./type.js");
const readTemMainTemp = require("./readTemMainTemp.js");

function getCodes(spaceConf, option, name, successMessages) {
  const { copyFile, updateAlias } = spaceConf;
  const spacePath = path.join(cwd, spaceConf.repertoryPath);
  dir.mk(spacePath);
  // 进入代码存放目录
  process.chdir(spacePath);
  // 获取所有未设置disabled 属性的代码仓库列表
  const repertoryList = spaceConf.repertoryList.filter(item => !item.disabled);
  const mainRepertory = spaceConf.mainRepertory;
  if (!mainRepertory) {
    // 未设置主仓库
    successMessages.push({
      type: "warn",
      msg: `未设置主仓库 ...`
    });
    log.bt("tips").t("you 'd better set an main repertory if this work space need some dependence!").end();
  } else if (!repertoryList.some(item => item.repertory.includes(mainRepertory))){
    // 主仓库未选中
    successMessages.push({
      type: "warn",
      msg: `主仓库未选中 ...`
    });
    log.bw("warn").w("you set an main repertory but none of these active repertories is  the one!").end();
  }
  // 检出各仓库分支·
  repertoryList.forEach(item => {
    const repertory = item.repertory;
    log.t(repertory).end();
    // packagePath.push(path.join(spacePath, item.name));
    try {
      // 克隆
      cProcess.execSync(`git clone ${item.repertory}`);
      log("succ:").use("bs")(`clone '${item.name}' success!`).use("s").end();
    } catch (e) {
    }
  });

  const {isDevTool} = spaceConf;
  if (isDevTool) return;
  const packages = getPackages(repertoryList, spacePath, successMessages);
  // 别名
  if (updateAlias) {
    writeAlias(packages, spacePath, spaceConf, option, name);
  }
  if (copyFile) {
    // 如果有主仓库 就将主仓库的 除了src | node_modules 全拷贝出去，
    copyFileFromMainRepertoryToWorkspaceRoot(spaceConf, successMessages);
    // 主要用于 index.html main.js 的拷贝，这两块自定义的地方多点// 可以没有
    execCustomFunctions(spaceConf, packages, option, name);
  }
}
function execCustomFunctions(spaceConf, confList, option, name) {
  const confPath = path.join(option.ctoolsOpt.devToolsDir, `ctools.conf/bizConfs`, name);
  const webpackFns = fs.readdirSync(confPath).map(item =>
    /\.fn\.js$/.test(item) ? require(path.join(confPath, item)) : undefined
  ).filter(item => item);
  webpackFns.forEach(fn =>
    type.isFunction(fn) && fn(confList, {
      smallHump: readTemMainTemp.smallHump,
      workspacePath: path.join(cwd, spaceConf.repertoryPath),
      log,
      dir
    })
  );
}
function copyFileFromMainRepertoryToWorkspaceRoot(spaceConf, successMessages) {
  try {
    if (spaceConf.mainRepertory) {
      const targetRootPath = path.join(cwd, spaceConf.repertoryPath);
      const oriRootPath = path.join(targetRootPath, spaceConf.mainRepertory);
      fs.readdirSync(oriRootPath).forEach(item => {
        if (!/^(src|node_modules|\.git)$/.test(item)) {
          dir.copy(path.join(oriRootPath, item), path.join(targetRootPath, item))
        }
      });
    }
  } catch (e) {
    const targetRootPath = path.join(cwd, spaceConf.repertoryPath);
    const oriRootPath = path.join(targetRootPath, spaceConf.mainRepertory);
    successMessages.push({
      type: "err",
      msg: `copy file '${oriRootPath}' to '${targetRootPath}' fail! ...`
    });
    log.be("fail:").e(`copy file '${oriRootPath}' to '${targetRootPath}' fail!`).end();
  }
}

function writeAlias(confList, spacePath, spaceConf, option, name) {
  const confPath = path.join(option.ctoolsOpt.devToolsDir, `ctools.conf/bizConfs`, name);
  const webpackConfAlias = {};
  const abledRepertoryList = spaceConf.repertoryList.filter(item => !item.disabled);
  confList.forEach((packageJson, index) => {
    setWebPackConfAlias(packageJson, spacePath, spaceConf, abledRepertoryList[index],webpackConfAlias);
  });
  console.log(path.join(confPath, `alias.json`))
  fs.writeFileSync(path.join(confPath, `alias.json`), JSON.stringify({
    resolve: {extensions: ['.js', '.vue', '.json'], alias: webpackConfAlias}
  }));
  log("succ:").use("bs")(`write 'alias.json' success!`).use("s").end();
}
function setWebPackConfAlias(packageJson, spacePath, spaceConf, curSpace,webpackConfAlias) {
  const repertoryPath = path.join(spacePath, curSpace.name);
  const name = packageJson.name;
  const map = (spaceConf.alias || {})[name] || {};

  console.log(name)
  if (/wxm/.test(name) || /(app-|-app|pc-|-pc)/g.test(name)) {
    const srcName = /wxm/.test(name) ? name : name.replace(/(app-|-app|pc-|-pc)/g, "");
    webpackConfAlias[`@${srcName}`] = `${repertoryPath}${map.src || ""}`;
    webpackConfAlias[`${name}`] = `${repertoryPath}`;
  } else {
    const srcName = packageJson.name;
    console.log(
      srcName,
      `${repertoryPath}${fs.readdirSync(repertoryPath).includes("src") ? `/src` : ``}`,
      path.join(repertoryPath, (packageJson.main || "").replace(/index\.js/, ""))
    )
    webpackConfAlias[`@${srcName}`] = `${repertoryPath}${fs.readdirSync(repertoryPath).includes("src") ? `/src` : ``}`;
    webpackConfAlias[`${name}`] = path.join(repertoryPath, (packageJson.main || "").replace(/index\.js/, ""));
  }
}

function getPackages(list, spacePath, successMessages) {
  return list.map(item => {
    try {
      const repertoryPath = path.join(spacePath, item.name);
      const packageInfo = require(path.join(repertoryPath, `./package.json`));
      dir.mk(path.join(repertoryPath, "./static"));
      return packageInfo;
    } catch (e) {
      successMessages.push({
        type: "err",
        msg: `try get '${item}/package.json' fail. it may be caused by empty repertory!`
      });
      log("fail:").use("bw")(`try get '${item}/package.json' fail. it may be caused by empty repertory!`).use("w").end();
    }
  }).filter(item => item);
}
module.exports = getCodes;
